#pragma once 
#include "protocol.hpp"
#include <string>

namespace ns_client
{
  class Client
  {
    private:
      std::string svr_ip;
      uint16_t svr_port;
      int sock;
    public:
      Client(const std::string &_ip, uint16_t _port)
        : svr_ip(_ip)
          , svr_port(_port)
          , sock(-1)
      {}

      void InitClient()
      {
        sock = socket(AF_INET, SOCK_STREAM, 0);
        if(sock < 0)
        {
          std::cerr << "socket error" << std::endl;
          exit(2);
        }
        //不需要手动bind、listen、accept
      }

      void Run()
      {
        struct sockaddr_in peer;
        bzero(&peer, sizeof(peer));

        peer.sin_family = AF_INET;
        peer.sin_port = htons(svr_port);
        peer.sin_addr.s_addr = inet_addr(svr_ip.c_str());

        int ret = connect(sock, (struct sockaddr*)&peer, sizeof(peer));
        if(ret < 0)
        {
          std::cerr << "connect error" << std::endl;
          exit(3);
        }

        while(true)
        {
          ns_protocol::Request req;
          std::cout << "请输入你的第一个数据# ";
          std::cin >> req.x;
          std::cout << "请输入你的第二个数据# ";
          std::cin >> req.y;
          std::cout << "请输入要进行的计算<+-*/%># ";
          std::cin >> req.op;

          //暂时省略将req序列化的过程
          send(sock, &req, sizeof(req), 0);

          ns_protocol::Response resp;
          ssize_t s = recv(sock, &resp, sizeof(resp), 0);
          if(s > 0)
          {
            //暂时省略将resp反序列化的过程
            std::cout << "code: " << resp.code << std::endl;
            std::cout << "result: " << resp.result << std::endl;
          }
        }
      }

      ~Client()
      {
        if(sock >= 0) close(sock);
      }
  };
}

